package com.web44.spring.advice;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/**
 * @Title: LogAdvice
 * @Description:
 * @Auther: py
 * @Version: 1.0
 * @create 2024/1/9 15:31
 * 通知类
 *  @Before           被代理方法执行前完成
 *  @AfterReturning   被代理方法执行完成后并且可以接收到返回值
 *  @AfterThrowing    被代理方法执行产生了异常 并且结束
 *                    @AfterThrowing 捕获到了异常 @AfterReturning 不会执行了 但是 @After  会执行
 *  @After            被代理方法执行完成后无法获取返回值
 *  @Around     环绕通知  【足够了】 灵活性是最好的
 *     1. 环绕前置  先于  @Before   执行的
 *     2. 环绕后置返回  晚于 @After 执行的
 *     3. 环绕异常 晚于 @After 执行的  对异常进行捕获处理
 *
 * execution 表达式
 *     * 匹配一个包、类、方法
 *     .. 匹配包的所有的包和类  匹配所有的参数
 */
@Component
public class LogAdviceXml {

    @Pointcut("execution(* com.web44.spring.service.impl..*(..))")
    public void pointCut() {

    }


    public void beforeMethod(JoinPoint point) {
        // 获取方法名字
        String name = point.getSignature().getName();
        // 获取方法的参数
        Object[] args = point.getArgs();
        System.out.println("[前置通知日志] "+name+" 方法开始了，参数是："+ Arrays.toString(args));
    }


    public void returnMethod(JoinPoint point,Object result) {
        // 获取方法名字
        String name = point.getSignature().getName();
        // 获取方法的参数
        Object[] args = point.getArgs();
        System.out.println("[返回通知日志] "+name+" 方法结束了，参数是："+ Arrays.toString(args)+"返回值是"+result);
    }


    public void afterMethod(JoinPoint point) {
        // 获取方法名字
        String name = point.getSignature().getName();
        // 获取方法的参数
        Object[] args = point.getArgs();
        System.out.println("[后置通知日志] "+name+" 方法结束了，参数是："+ Arrays.toString(args));
    }


    public void afterThrowingMethod(JoinPoint point,Throwable throwable) {
        // 获取方法名字
        String name = point.getSignature().getName();
        // 获取方法的参数
        Object[] args = point.getArgs();
        System.out.println("[异常通知日志] "+name+" 方法结束了，参数是："+ Arrays.toString(args)+",异常清空"+throwable.toString());
    }


    public void aroundMethod(ProceedingJoinPoint point) {
        // 获取方法名字
        String name = point.getSignature().getName();
        // 获取方法的参数
        Object[] args = point.getArgs();
        try {

            // 前置通知
            System.out.println("[环绕前置通知日志] "+name+" 方法开始了，参数是："+ Arrays.toString(args));
            Object reuslt = point.proceed(); // 待增强的方法执行了  并且给了返回值
            // 后置通知  后置返回通知
            System.out.println("[环绕返回通知日志] "+name+" 方法结束了，参数是："+ Arrays.toString(args)+"返回值是"+reuslt);
        } catch (Throwable e) {
            System.out.println("[环绕异常通知日志] "+name+" 方法结束了，参数是："+ Arrays.toString(args)+",异常清空"+e.toString());
        }

    }
}
